package com.automapper.interceptor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.automapper.constants.ParameterConstants;
import com.automapper.utils.ParameterUtils;

/**
 * 该拦截在mybatis调用Executor的query和update方法进行参数拦截，
 * 拦截通过调用AutoMapperRepository接口的方法时传入参数是null或集合是空集合，终止后续所有拦截器操作。
 * 注意：调用AutoMapperRepository.select方法传入参数是null或集合是空集合，将会返回空集合。
 * @author K
 *
 */
@Intercepts({
    @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class,ResultHandler.class }),
    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class }) 
})
public class AutoMapperCheckEmptyInterceptor implements Interceptor {
	
	private static final Logger logger = LoggerFactory.getLogger(AutoMapperCheckEmptyInterceptor.class);
	
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		//获取传入的参数
		Object parameter = invocation.getArgs()[1];
				
		// parameter不是通过AutoMapperRepository方法传入参数，不做任何处理，传递给下一个拦截器处理
		if (!ParameterUtils.isAutoMapperParameter(parameter)) {
			return invocation.proceed();
		}
		
		Map<String, Object> parameterMap = (Map<String, Object>) parameter;
		parameter = parameterMap.get(ParameterConstants.PARAM);
		if (parameter == null) {
			logger.warn("逗比，你传入的对象是null，要注意喔");
			return getDefaultReturnValue(invocation);
		}
		
		if (parameter instanceof Collection && CollectionUtils.isEmpty((Collection<?>) parameter)) {
			logger.warn("逗比，你传入的集合对象size=0，要注意喔");
			return getDefaultReturnValue(invocation);
		}
		
        return invocation.proceed();
	}
	
	private Object getDefaultReturnValue(Invocation invocation) {
        Class<?> returnType = invocation.getMethod().getReturnType();
        if (returnType.equals(List.class)) {
            return new ArrayList<Object>();
        } else if ("int".equalsIgnoreCase(returnType.toString())) {
        	//调用的方法没有返回值（void），returnType就是int类型
        	return 0;
        }
        return null;
    }

	@Override
	public Object plugin(Object target) {
		if (target == null) {
			return target;
        } 
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {}
}
